package com.xiaochong.tir.api.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.sun.org.apache.xpath.internal.operations.Bool;
import com.xc.logclient.utils.LogTrace;
import com.xiaochong.tir.api.component.HbaseBaseQueryComponent;
import com.xiaochong.tir.api.component.RedisCacheComponent;
import com.xiaochong.tir.api.util.StringUtil;
import com.xiaochong.tir.common.data.hbasepo.*;
import com.xiaochong.tir.common.data.mapper.CurrencyInfoMapper;
import com.xiaochong.tir.common.data.po.CurrencyInfo;
import com.xiaochong.tir.common.data.vo.*;
import com.xiaochong.tir.common.exception.hbase.HbaseCloseExcetion;
import com.xiaochong.tir.common.exception.hbase.HbaseConnectionExcetion;
import com.xiaochong.tir.common.exception.hbase.HbaseGetTableExcetion;
import com.xiaochong.tir.common.util.ApiResultCodeUtils;
import com.xiaochong.tir.common.util.DateUtils;
import com.xiaochong.tir.common.util.HbaseTableUtils;
import com.xiaochong.tir.common.util.RedisKeysUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.zookeeper.server.quorum.FastLeaderElection;
import org.springframework.beans.factory.annotation.Autowired;
import com.xiaochong.service.common.config.redis.RedisServer;
import org.springframework.stereotype.Service;
import scala.util.parsing.combinator.testing.Str;

import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

/**
 * Created by org on 2018/5/2.
 * 货币诊断service
 */
@Service
public class CurrencyDiagnosisService {
    @Autowired
    private RedisServer rediscConfig ;
    @Autowired
    private HbaseBaseQueryComponent hbaseBaseQueryComponent;
    @Autowired
    private CurrencyInfoMapper currencyInfoMapper;
    @Autowired
    private RedisCacheComponent redisCacheComponent;

    @Autowired
    private ExchangeInfoService exchangeInfoService;

    /**
     * 量化评估-市场热度
     * @return
     */
    public ApiResultVo<ApiMarketHeatVo> getMarketHeatList(String cmc_id) {
        Long start = System.currentTimeMillis();
        ApiResultVo resultVo = new ApiResultVo();
        ApiMarketHeatVo vo = new ApiMarketHeatVo();
        resultVo.setTradeId(LogTrace.getTrace().getTraceId());
        resultVo.setDataStamp(System.currentTimeMillis());
        try {
            String redisDate = rediscConfig.get(RedisKeysUtils.DIAGNOSIS_MARKET_HEATLIST+cmc_id);
            LogTrace.info("量能变化reis查询数据","耗时",String.valueOf(System.currentTimeMillis()-start));
            if(StringUtils.isNotBlank(redisDate)){
                vo = JSON.parseObject(redisDate,ApiMarketHeatVo.class);
            }else{//去hbase获取并且保存到redis中
                this.MarketHeatListToCacheCalculation(vo,cmc_id);
            }
            if(vo == null){
                resultVo.setCode(ApiResultCodeUtils.SYSTEM_NULL.getCode());
                resultVo.setMessage(ApiResultCodeUtils.SYSTEM_NULL.getMsg());
            }else{
                resultVo.setCode(ApiResultCodeUtils.BASE_SUCCESS.getCode());
                resultVo.setMessage(ApiResultCodeUtils.BASE_SUCCESS.getMsg());
            }
            resultVo.setData(vo);
            Long end = System.currentTimeMillis();
            LogTrace.info("市场热度","耗时",String.valueOf(end-start));
            return resultVo;
        } catch (Exception e) {
            e.printStackTrace();
            resultVo.setCode(ApiResultCodeUtils.SYSTEM_ERROR.getCode());
            resultVo.setMessage(ApiResultCodeUtils.SYSTEM_ERROR.getMsg());
            LogTrace.error("量化评估-市场热度",e);
            Long end = System.currentTimeMillis();
            LogTrace.info("市场热度","耗时",String.valueOf(end-start));
            return resultVo;
        }


    }

    /**
     * 量化评估-量能变化
     * @param cmc_id  货币id
     * @return
     */
    public ApiResultVo<ApiEnergyVolumeChangeVo> getEnergyVolumeChange(String cmc_id) {
        long start = System.currentTimeMillis();
        ApiResultVo resultVo = new ApiResultVo();
        ApiEnergyVolumeChangeVo vo = new ApiEnergyVolumeChangeVo();
        resultVo.setDataStamp(System.currentTimeMillis());
        resultVo.setTradeId(LogTrace.getTrace().getTraceId());
        LogTrace.info("量化评估-量能变化","cmc_id",cmc_id);
        try {
            String redisDate = rediscConfig.get(RedisKeysUtils.DIAGNOSIS_ENERGY_VOLUME_CHANGE+cmc_id);
            LogTrace.info("量能变化reis查询数据","耗时",String.valueOf(System.currentTimeMillis()-start));
            if(StringUtils.isNotBlank(redisDate)){
                vo = JSON.parseObject(redisDate,ApiEnergyVolumeChangeVo.class);
            }else{//去hbase获取并且保存到redis中
                this.makeEnergyVolumeChangeToCacheCalculation(vo,cmc_id);
            }
            if(vo == null){
                resultVo.setCode(ApiResultCodeUtils.SYSTEM_NULL.getCode());
                resultVo.setMessage(ApiResultCodeUtils.SYSTEM_NULL.getMsg());
            }else{
                resultVo.setCode(ApiResultCodeUtils.BASE_SUCCESS.getCode());
                resultVo.setMessage(ApiResultCodeUtils.BASE_SUCCESS.getMsg());
            }
            resultVo.setData(vo);
            Long end = System.currentTimeMillis();
            LogTrace.info("量化评估-量能变化","耗时",String.valueOf(end-start));
            return resultVo;
        } catch (Exception e) {
            LogTrace.error("量化评估-量能变化",e);
            Long end = System.currentTimeMillis();
            LogTrace.info("量化评估-量能变化","耗时",String.valueOf(end-start));
            e.printStackTrace();
            resultVo.setCode(ApiResultCodeUtils.SYSTEM_ERROR.getCode());
            resultVo.setMessage(ApiResultCodeUtils.SYSTEM_ERROR.getMsg());
            return resultVo;
        }
    }
    /**
     * 量化评估-货币流动性
     * @return
     */
    public ApiResultVo<ApiCurrencyExchangeRatetVo> getCurrencyExchangeRate(String cmc_id) {
        Long start = System.currentTimeMillis();
        ApiResultVo resultVo = new ApiResultVo();
        ApiCurrencyExchangeRatetVo vo = new ApiCurrencyExchangeRatetVo();
        resultVo.setDataStamp(System.currentTimeMillis());
        resultVo.setTradeId(LogTrace.getTrace().getTraceId());
        LogTrace.info("量化评估-货币流动性参数","cmc_id",cmc_id);
        try {
            String redisDate = rediscConfig.get(RedisKeysUtils.DIAGNOSIS_CURRENCY_EXCHANGE_RATE+cmc_id);
            LogTrace.info("货币流动性reis查询数据","耗时",String.valueOf(System.currentTimeMillis()-start));
            if(StringUtils.isNotBlank(redisDate)){
                vo = JSON.parseObject(redisDate,ApiCurrencyExchangeRatetVo.class);
            }else{//去hbase获取并且保存到redis中
                this.marketCurrencyExchangeRateToCacheCalculation(vo,cmc_id);
            }
            if(vo == null){
                resultVo.setCode(ApiResultCodeUtils.SYSTEM_NULL.getCode());
                resultVo.setMessage(ApiResultCodeUtils.SYSTEM_NULL.getMsg());
            }else{
                resultVo.setCode(ApiResultCodeUtils.BASE_SUCCESS.getCode());
                resultVo.setMessage(ApiResultCodeUtils.BASE_SUCCESS.getMsg());
            }
            resultVo.setData(vo);
            Long end = System.currentTimeMillis();
            LogTrace.info("量化评估-货币流动性一共耗时","耗时",String.valueOf(end-start));
            return resultVo;
        } catch (Exception e) {
            e.printStackTrace();
            Long end = System.currentTimeMillis();
            LogTrace.info("量化评估-货币流动性错误耗时","耗时",String.valueOf(end-start));
            LogTrace.error("量化评估-货币流动性",e);
            resultVo.setCode(ApiResultCodeUtils.SYSTEM_ERROR.getCode());
            resultVo.setMessage(ApiResultCodeUtils.SYSTEM_ERROR.getMsg());
            return resultVo;
        }
    }
    /**
     * 量化评估-人气意愿指标
     * @return
     */
    public ApiResultVo<ApiPopularityARIndexVo> getPopularityARIndex(String cmc_id) {
        Long start = System.currentTimeMillis();
        ApiResultVo resultVo = new ApiResultVo();
        ApiPopularityARIndexVo vo = new ApiPopularityARIndexVo();
        resultVo.setDataStamp(System.currentTimeMillis());
        resultVo.setTradeId(LogTrace.getTrace().getTraceId());
        LogTrace.info("量化评估-人气意愿指标","cmc_id",cmc_id);
        try {
            //从redis获取
            Long hstart = System.currentTimeMillis();
            int nowHours = LocalDateTime.now().getHour();//当前小时
            String allDayDate = rediscConfig.get(RedisKeysUtils.AR_HEAT_INDEX_ALL_DATA+cmc_id);
            if(StringUtils.isNotBlank(allDayDate)){
                List<String> x = new LinkedList<>();
                List<ApiChartYObject> y = new LinkedList<>();
                int days = 0;
                boolean changeFlag = false;
                boolean firstFlag = true;
                ApiChartYObject charY = null;
                Map<String, List<PopularityIndicator>> popularityIndicatorListMap = JSON.parseObject(allDayDate,new TypeReference<Map<String, List<PopularityIndicator>>>(){});
                PopularityIndicator pop = new PopularityIndicator();
                for(int i=0;i<10;i++) {
                    //获取十天内数据
                    String rowKey = DateUtils.getNextDayDateYMD(days);
                    days--;
                    List<PopularityIndicator> popList= popularityIndicatorListMap.get(rowKey);
                    if(popList == null || popList.size() == 0){//如果数据为空再去hbase查询当前rowkey数据是否存在
                        popList = getPopularityDayARIndexFromHbase(rowKey,cmc_id);
                        if(popList != null && popList.size() != 0){
                            for(int day =0;day < popList.size();day++){
                                pop = popList.get(day);
                                if(pop != null && pop.getComment() != null && pop.getId() != null && pop.getAr() != null && pop.getCreateTime() != null && pop.getScore() != null){
                                    changeFlag = true;
                                    popularityIndicatorListMap.put(rowKey,popList);
                                }
                            }
                        }
                    }
                    if(popList == null || popList.size() == 0) continue;
                    for(int k=0;k<popList.size();k++){
                        pop = popList.get(k);
                        x.add(String.valueOf(pop.getCreateTime().getTime()));
                        String ar =pop.getAr()!=null?pop.getAr().setScale(2,BigDecimal.ROUND_DOWN).toString():"";
                        charY = new ApiChartYObject();
                        charY.setValue(ar);
                        charY.setScore(pop.getScore().toString());
                        charY.setComment(pop.getComment());
                        y.add(charY);
                        //实体插入第一次的成交量和平均价格
                        if(firstFlag){
                            vo.setArScore(ar);
                            vo.setScore(pop.getScore()!=null?pop.getScore().toString():"");
                            vo.setResult(pop.getComment()!=null?pop.getComment():"");
                            vo.setTime(pop.getCreateTime()!=null?String.valueOf(pop.getCreateTime().getTime()):"");
                            firstFlag = false;
                        }
                    }
                    LogTrace.info("量化评估-人气意愿指标redis当前rowkey","rowKey",rowKey);
                   /* if(firstFlag){
                        vo.setArScore(pop.getAr().setScale(2,BigDecimal.ROUND_DOWN).toString());
                        vo.setResult(pop.getComment());
                        vo.setScore(pop.getScore().toString());
                        vo.setTime(String.valueOf(pop.getCreateTime().getTime()));
                        firstFlag = false;
                    }*/
                }
                ChartVo charvo = new ChartVo();
                //顺序反转
                Collections.reverse(x);
                Collections.reverse(y);
                charvo.setX(x);
                charvo.setY(y);
                vo.setChart(charvo);
                if(changeFlag){ //redis中数据不全，需要重新set
                    rediscConfig.set(RedisKeysUtils.AR_HEAT_INDEX_ALL_DATA+cmc_id,JSON.toJSONString(popularityIndicatorListMap));
                }
                LogTrace.info("量化评估-人气意愿指标redis数据查询","耗时",String.valueOf(System.currentTimeMillis()-hstart));
            }else{
                //获取不到从hbase获取
                this.makePopularityARIndexDataOfHbase(vo,cmc_id);
            }

            Long end = System.currentTimeMillis();
            vo.setSortId(4);
            vo.setClassify("人气意愿指标");
            vo.setExplanation("人气指标（AR）是通过比较一段周期内的开盘价在该周期价格中的高低，从而反映市场买卖人气的技术指标。当AR大于120，表明买方意愿强。当AR小于60，表明卖方意愿强。");
            LogTrace.info("量化评估-人气指标","耗时",String.valueOf(end-start));
            resultVo.setData(vo);
            //判断空
            List<String> x = vo.getChart().getX();
            List<String> y = (List<String>) vo.getChart().getY();
            if(x == null || y == null || x.size() == 0 || y.size() == 0 ){
                resultVo.setCode(ApiResultCodeUtils.SYSTEM_NULL.getCode());
                resultVo.setMessage(ApiResultCodeUtils.SYSTEM_NULL.getMsg());
            }else{
                resultVo.setCode(ApiResultCodeUtils.BASE_SUCCESS.getCode());
                resultVo.setMessage(ApiResultCodeUtils.BASE_SUCCESS.getMsg());
            }
            return resultVo;
        } catch (Exception e) {
            Long end = System.currentTimeMillis();
            LogTrace.info("量化评估-人气指标","耗时",String.valueOf(end-start));
            LogTrace.error("量化评估-人气指标",e);
            e.printStackTrace();
            resultVo.setCode(ApiResultCodeUtils.SYSTEM_ERROR.getCode());
            resultVo.setMessage(ApiResultCodeUtils.SYSTEM_ERROR.getMsg());
            return resultVo;
        }
    }

    /**
     * 量化评估-人气意愿指标
     * @return
     */
    public ApiResultVo<ApiPopularityARIndexVo> getPopularityARIndexOfHours(String cmc_id) {
        Long start = System.currentTimeMillis();
        ApiResultVo resultVo = new ApiResultVo();
        ApiPopularityARIndexVo vo = new ApiPopularityARIndexVo();
        resultVo.setDataStamp(System.currentTimeMillis());
        resultVo.setTradeId(LogTrace.getTrace().getTraceId());
        LogTrace.info("量化评估-人气意愿指标","cmc_id",cmc_id);
        try {
            //boolean isNowHours = true;//判断是否存在当前小时数据
            Long hstart = System.currentTimeMillis();
            String allDayDate = rediscConfig.get(RedisKeysUtils.AR_HEAT_INDEX_ALL_DATA_HOURS+cmc_id);//从redis获取
            if(StringUtils.isNotBlank(allDayDate)){
                vo = JSON.parseObject(allDayDate,ApiPopularityARIndexVo.class);
                List<String> xdate =  vo.getChart().getX();
                if(vo != null && xdate != null || xdate.size() > 0 ){
                    Long dateLong = Long.valueOf(xdate.get(xdate.size()-1));
                    int nowHours = LocalDateTime.now().getHour();//当前小时
                    int redisLastHours = DateUtils.getDateTimeOfTimestamp(dateLong).getHour();//redis最后一条时间
                    if(redisLastHours != nowHours){ //判断最后一条数据是否是当前时间，如果不是也要从新查找hbase
                        allDayDate = "";
                        LogTrace.info("量化评估-人气意愿指标redis数据查询","最后一条时间",String.valueOf(redisLastHours));
                    }
                }
                LogTrace.info("量化评估-人气意愿指标redis数据查询","耗时",String.valueOf(System.currentTimeMillis()-hstart));
            }
            if(StringUtils.isBlank(allDayDate)){//获取不到从hbase获取
                this.makePopularityARIndexHoursDataOfHbase(vo,cmc_id);
            }
            //判断空
            List<String> x =  vo.getChart().getX();
            List<String> y = (List<String>) vo.getChart().getY();
            Long end = System.currentTimeMillis();
            LogTrace.info("量化评估-人气指标","耗时",String.valueOf(end-start));
            resultVo.setData(vo);
            if(vo == null ||x == null || y == null || x.size() == 0 || y.size() == 0 ){
                resultVo.setCode(ApiResultCodeUtils.SYSTEM_NULL.getCode());
                resultVo.setMessage(ApiResultCodeUtils.SYSTEM_NULL.getMsg());
            }else{
                resultVo.setCode(ApiResultCodeUtils.BASE_SUCCESS.getCode());
                resultVo.setMessage(ApiResultCodeUtils.BASE_SUCCESS.getMsg());
            }
            return resultVo;
        } catch (Exception e) {
            Long end = System.currentTimeMillis();
            LogTrace.info("量化评估-人气指标","耗时",String.valueOf(end-start));
            LogTrace.error("量化评估-人气指标",e);
            e.printStackTrace();
            resultVo.setCode(ApiResultCodeUtils.SYSTEM_ERROR.getCode());
            resultVo.setMessage(ApiResultCodeUtils.SYSTEM_ERROR.getMsg());
            return resultVo;
        }
    }
    /**
     * 获取诊断得分
     * @param cmc_id
     * @return
     */
    public ApiResultVo<ApiCurrencyDiagnosisScoreVo> getCurrencyDiagnosisScore(String cmc_id) {
        Long start = System.currentTimeMillis();
        ApiResultVo resultVo = new ApiResultVo();
        resultVo.setDataStamp(System.currentTimeMillis());
        resultVo.setTradeId(LogTrace.getTrace().getTraceId());
        LogTrace.info("量化评估-获取诊断得分","cmc_id",cmc_id);
        try {
            ApiCurrencyDiagnosisScoreVo vo = new ApiCurrencyDiagnosisScoreVo();
            String redisDate = rediscConfig.get(RedisKeysUtils.DIAGNOSIS_CURRENCY_SCORE_INFO+cmc_id);
            LogTrace.info("获取诊断得分reis查询数据","耗时",String.valueOf(System.currentTimeMillis()-start));
            if(StringUtils.isNotBlank(redisDate)){
                vo = JSON.parseObject(redisDate,ApiCurrencyDiagnosisScoreVo.class);
            }else{//去hbase获取并且保存到redis中
                boolean isSuccess = this.MakeCurrencyDiagnosisScore(vo,cmc_id);
                if(!isSuccess){
                    resultVo.setCode(ApiResultCodeUtils.SYSTEM_NULL.getCode());
                    resultVo.setMessage(ApiResultCodeUtils.SYSTEM_NULL.getMsg());
                }
            }
            resultVo.setCode(ApiResultCodeUtils.BASE_SUCCESS.getCode());
            resultVo.setMessage(ApiResultCodeUtils.BASE_SUCCESS.getMsg());

            vo.setLast7status(rediscConfig.get(RedisKeysUtils.CMC_DATA_7_STATUS+cmc_id));
            vo.setLast30status(rediscConfig.get(RedisKeysUtils.CMC_DATA_30_STATUS+cmc_id));


            //获取多空行情
            String rowkey = cmc_id + "@" +DateUtils.getNextDayDateYMD(-1);//取rowkey

            String space = hbaseBaseQueryComponent.selectByQualifierData( HbaseTableUtils.LONG_AND_SHORT_TREND_TABLE_NAME
                    , HbaseTableUtils.LONG_AND_SHORT_TREND_TABLE_NAME_FAMILY
                    , HbaseTableUtils.LONG_AND_SHORT_TREND_TABLE_NAME_QUALIFIER
                    , rowkey
            );
            //压力支撑
            String press = hbaseBaseQueryComponent.selectByQualifierData( HbaseTableUtils.CURRENCY_DIAGNOSIS_PRESSURE_SUPPORT_TABLE_NAME
                    , HbaseTableUtils.CURRENCY_DIAGNOSIS_PRESSURE_SUPPORT_TABLE_FAMILY
                    , HbaseTableUtils.CURRENCY_DIAGNOSIS_PRESSURE_SUPPORT_QUALIFIER
                    , rowkey

            );
            //平均成本
            String avg = hbaseBaseQueryComponent.selectByQualifierData( HbaseTableUtils.CURRENCY_DIAGNOSIS_AVERAGE_COST_INFO_TABLE_NAME
                    , HbaseTableUtils.CURRENCY_DIAGNOSIS_AVERAGE_COST_INFO_TABLE_FAMILY
                    , HbaseTableUtils.CURRENCY_DIAGNOSIS_AVERAGE_COST_INFO_QUALIFIER
                    , rowkey
            );

            JSONObject jsonSpace = JSON.parseObject( space );
            JSONObject jsonPress = JSON.parseObject( press );
            JSONObject jsonAvg = JSON.parseObject( avg );

            for (int j = 24; j>0; j--) {

                if(StringUtils.isBlank(vo.getSpaceTrendComment()) && jsonSpace != null){
                    JSONArray jsonArray = jsonSpace.getJSONArray(j +"");
                    if(jsonArray!= null){
                        JSONObject jsonObject = (JSONObject) jsonArray.get( jsonArray.size() - 1 );
                        vo.setSpaceTrendComment(jsonObject.getString("comment"));
                    }
                }

                if(StringUtils.isBlank(vo.getPressureSupComment()) && jsonPress != null){
                    JSONArray jsonArray = jsonPress.getJSONArray(j +"");
                    if(jsonArray!= null){
                        JSONObject jsonObject = (JSONObject) jsonArray.get( jsonArray.size() - 1 );
                        vo.setPressureSupComment(jsonObject.getString("comment"));
                    }
                }

                if(StringUtils.isBlank(vo.getAvgCostComment()) && jsonAvg != null){
                    JSONArray jsonArray = jsonAvg.getJSONArray(j +"");
                    if(jsonArray!= null){
                        JSONObject jsonObject = (JSONObject) jsonArray.get( jsonArray.size() - 1 );
                        vo.setAvgCostComment(jsonObject.getString("comment"));
                    }
                }


            }

            resultVo.setData(vo);
            Long end = System.currentTimeMillis();

            LogTrace.info("量化评估-诊断得分","耗时",String.valueOf(end-start));
            return resultVo;
        } catch (Exception e) {
            LogTrace.error("量化评估-诊断得分",e);
            Long end = System.currentTimeMillis();
            LogTrace.info("量化评估-诊断得分","耗时",String.valueOf(end-start));
            e.printStackTrace();
            resultVo.setCode(ApiResultCodeUtils.SYSTEM_ERROR.getCode());
            resultVo.setMessage(ApiResultCodeUtils.SYSTEM_ERROR.getMsg());
            return resultVo;
        }
    }

    /**
     * 组装货币诊断得分到redis中
     * @param vo
     * @param cmc_id
     * @throws Exception
     */
    public boolean MakeCurrencyDiagnosisScore(ApiCurrencyDiagnosisScoreVo vo,String cmc_id) throws Exception{
        String grailStr = null;
        //获取当前小时
        Long hstartt = System.currentTimeMillis();
        String rowKey = "";
        int day =0;
        while (StringUtils.isBlank(grailStr)){//循环获取，指导获取到数据
            rowKey = DateUtils.getNextDayDateYMD(day);
            grailStr = hbaseBaseQueryComponent.selectByQualifierData(HbaseTableUtils.CURRENCY_DIAGNOSIS_SCORE_TABLE_NAME
                    , HbaseTableUtils.CURRENCY_DIAGNOSIS_SCORE_TABLE_FAMILY
                    , HbaseTableUtils.CURRENCY_DIAGNOSIS_SCORE_QUALIFIER
                    , cmc_id+"@"+rowKey);//DateUtils.getCurrentDateString()
            day --;
            if(StringUtils.isNotBlank(grailStr) || day <-7){
                break;
            }
        }
        LogTrace.info("hbase数据查询",rowKey+"是否存在数据"+cmc_id,StringUtils.isBlank(grailStr)?"无数据":"有数据");
        if(StringUtils.isBlank(grailStr)){
            return false;
        }
        //数据库查询模型symbol
        CurrencyInfo queryInfo = new CurrencyInfo();
        queryInfo.setCmcId(cmc_id);
        Long dstart = System.currentTimeMillis();
        // CurrencyInfo infoList  =  currencyInfoMapper.selectByEntity(queryInfo);
        CurrencyInfo info = redisCacheComponent.getCurrencyInfo(cmc_id);
        LogTrace.info("量化评估-获取诊断得分-redis查询","耗时",String.valueOf(System.currentTimeMillis()-dstart));
        //获取指定货币量能变化  DiagnosisQuantumEnergy
        Map<String,Object> diagnosisMap = JSON.parseObject(grailStr);
        String dataDiagnosi = "";
        int maxHour = 0;
        //获取最后数据
        for(Map.Entry<String,Object> maxMap : diagnosisMap.entrySet()){
            int tempHour = Integer.valueOf(maxMap.getKey());
            if(tempHour >= maxHour){
                maxHour = tempHour;
                //dataDiagnosi = JSON.toJSONString(diagnosisMap.get(String.valueOf(hourStr)));
                dataDiagnosi = JSON.toJSONString(maxMap.getValue());
            }
        }
        LogTrace.info("量化评估-获取诊断得分-时间",String.valueOf(maxHour),StringUtils.isBlank(dataDiagnosi)?"无数据":"有数据");
        List<DiagnosisScore> diagnosisScoreList = JSON.parseArray(dataDiagnosi,DiagnosisScore.class);
        if(diagnosisScoreList == null || diagnosisScoreList.size() == 0) return false;
        DiagnosisScore diagnosisScore = diagnosisScoreList.get(diagnosisScoreList.size()-1);
        vo.setDiagnosisId(cmc_id);
        vo.setScore(diagnosisScore.getDiagnosisScore().setScale(1, BigDecimal.ROUND_DOWN).toString());
        //记录内容是否为空
        LogTrace.info("量化评估-获取诊断得分-量能、流动、市场、ar人气数据","数据",JSON.toJSONString(diagnosisScore));
        //评语
        vo.setEnergyChange(diagnosisScore.getQuantumEnergyComment()!=null?diagnosisScore.getQuantumEnergyComment():"");
        vo.setCurrencyLiquidity(diagnosisScore.getLiquidityComment()!=null?diagnosisScore.getLiquidityComment():"");
        vo.setPopularityIndex(diagnosisScore.getPopularityIndicatorComment()!=null?diagnosisScore.getPopularityIndicatorComment():"");
        vo.setMarketHeat(diagnosisScore.getTrendsInfoResult()!=null && diagnosisScore.getTrendsInfoResult()!=null?diagnosisScore.getTrendsInfoResult():""); //市场热度评语
        vo.setWinPercent(diagnosisScore.getDefect()!=null?diagnosisScore.getDefect().multiply(BigDecimal.valueOf(100)).setScale(2,BigDecimal.ROUND_DOWN).toString():"0");  //打败
        //雷达图数据插入顺序 市场热度，人气指标，货币流动性，量能变化
        List<String> indicator = new ArrayList<>();
        indicator.add(diagnosisScore.getTrendsInfoScore()!=null&&diagnosisScore.getTrendsInfoScore()!=null?diagnosisScore.getTrendsInfoScore().toString():"0");//市场待取
        indicator.add(diagnosisScore.getPopularityIndicatorScore()!=null?diagnosisScore.getPopularityIndicatorScore().toString():"0");//ar人气指标
        indicator.add(diagnosisScore.getLiquidityScore()!=null?diagnosisScore.getLiquidityScore().toString():"0"); //货币流动性
        indicator.add(diagnosisScore.getQuantumEnergyScore()!=null?diagnosisScore.getQuantumEnergyScore().toString():"0");//量能变化
        vo.setIndicator(indicator);
        if(info!=null){
            vo.setSymbol(info.getSymbol());//插入模型
            vo.setCoinNameCn(info.getCoinNameCn());
            vo.setImageUrl(info.getImageUrl());
        }
        //数据插入到redis中
        rediscConfig.set(RedisKeysUtils.DIAGNOSIS_CURRENCY_SCORE_INFO+cmc_id,JSON.toJSONString(vo),300L);
        return  true;
    }
    /**
     * 获取所有启用的货币信息列表
     * @return
     */
    public ApiResultVo<List<ApiAllEnableCurrencyInfoVo>> getAllEnableCurrencyInfoList() {
        ApiResultVo resultVo = new ApiResultVo();
        try {
            resultVo.setDataStamp(System.currentTimeMillis());
            resultVo.setTradeId(LogTrace.getTrace().getTraceId());
            List<ApiAllEnableCurrencyInfoVo> list = currencyInfoMapper.getAllEnableCurrencyInfoList();
            resultVo.setData(list);
            resultVo.setCode(ApiResultCodeUtils.BASE_SUCCESS.getCode());
            resultVo.setMessage(ApiResultCodeUtils.BASE_SUCCESS.getMsg());
            return  resultVo;
        }catch (Exception e){
            e.printStackTrace();
            LogTrace.error("获取所有启用的货币信息列表",e);
            resultVo.setCode(ApiResultCodeUtils.SYSTEM_ERROR.getCode());
            resultVo.setMessage(ApiResultCodeUtils.SYSTEM_ERROR.getMsg());
            return  resultVo;
        }


    }

    /**
     * 组装ar人气到redis缓存
     * @param cmdIdList
     * @return
     */
    /*public ApiResultVo makePopularityARIndexData(List<PopularityIndicator> cmdIdList) {
        ApiResultVo resultVo = new ApiResultVo();
        resultVo.setTradeId(LogTrace.getTrace().getTraceId());
        resultVo.setDataStamp(System.currentTimeMillis());
        try {
            Date date = null;
            BigDecimal ar = null;
            String comment;
            Integer score;
            String cmcId;
            for(PopularityIndicator pop : cmdIdList){
                date = pop.getCreateTime();
                ar = pop.getAr();
                comment = pop.getComment();
                score = pop.getScore();
                cmcId = pop.getId();
                if(date == null || ar == null || comment == null || score == null || cmcId == null) {
                    continue;
                }
                //判断是否诊断货币，如果是才放入缓存中，否则过滤
                CurrencyInfo info = redisCacheComponent.getCurrencyInfo(cmcId);
                if(info == null || !info.getCurrencyDiagnosisFlag()){
                    continue;
                }
                String createDateStr = DateUtils.dateFormatString(date,DateUtils.format_ymds);
                Map<String,PopularityIndicator> popularityIndicatorMap = new HashMap<>();
                //获取单个货币缓存数据进行组装
                String allDayDate = rediscConfig.get(RedisKeysUtils.AR_HEAT_INDEX_ALL_DATA+cmcId);
                if(StringUtils.isNotBlank(allDayDate)){//数据放入redis中
                    popularityIndicatorMap = JSON.parseObject(allDayDate,new TypeReference<Map<String, PopularityIndicator>>(){});
                    String rowKeyExpire = DateUtils.getNextDayDateYMD(10);//获取第10天前的日期，过期数据
                    popularityIndicatorMap.remove(rowKeyExpire);
                    popularityIndicatorMap.put(createDateStr,pop);
                    rediscConfig.set(RedisKeysUtils.AR_HEAT_INDEX_ALL_DATA+cmcId,JSON.toJSONString(popularityIndicatorMap));
                }else{//第一次初始化
                    popularityIndicatorMap = this.makePopularityARIndexDataOfHbase(cmcId);
                }
                rediscConfig.set(RedisKeysUtils.AR_HEAT_INDEX_ALL_DATA+cmcId,JSON.toJSONString(popularityIndicatorMap));
            }
            resultVo.setCode(ApiResultCodeUtils.BASE_SUCCESS.getCode());
            resultVo.setMessage(ApiResultCodeUtils.BASE_SUCCESS.getMsg());
        }catch (Exception e){
            e.printStackTrace();
            LogTrace.error("ar人气指标定数据组装到redis中",e);
            resultVo.setCode(ApiResultCodeUtils.SYSTEM_ERROR.getCode());
            resultVo.setMessage(ApiResultCodeUtils.SYSTEM_ERROR.getMsg());
        }
        return  resultVo;
    }*/
    /**
     * 组装ar人气到redis缓存 akka
     * @return
     */
    public ApiResultVo makePopularityARIndexDataToCache() {
        ApiResultVo resultVo = new ApiResultVo();
        resultVo.setTradeId(LogTrace.getTrace().getTraceId());
        resultVo.setDataStamp(System.currentTimeMillis());
        try {
            String createDateStr = DateUtils.getCurrentDateString();
            Map<String,List<PopularityIndicator>> popularityIndicatorListMap = new HashMap<>();

            //获取所有货币,组装每个需要诊断数据放到redis中
            List<CurrencyInfo>  allCurrencyInfo = redisCacheComponent.getCurrencyList();
            if(allCurrencyInfo != null && allCurrencyInfo.size() > 0){
                for(CurrencyInfo currency : allCurrencyInfo){
                    if(currency.getCurrencyDiagnosisFlag()){
                        String cmcId = currency.getCmcId();
                        //获取单个货币缓存数据进行组装
                        String allDayDate = rediscConfig.get(RedisKeysUtils.AR_HEAT_INDEX_ALL_DATA+cmcId);
                        if(StringUtils.isNotBlank(allDayDate)){//数据放入redis中
                            List<PopularityIndicator> popList = getPopularityDayARIndexFromHbase(createDateStr,cmcId);//获取当天数据
                            popularityIndicatorListMap = JSON.parseObject(allDayDate,new TypeReference<Map<String, List<PopularityIndicator>>>(){});
                            String rowKeyExpire = DateUtils.getNextDayDateYMD(-10);//获取第10天前的日期，过期数据
                            popularityIndicatorListMap.remove(rowKeyExpire);
                            popularityIndicatorListMap.put(createDateStr,popList);
                            rediscConfig.set(RedisKeysUtils.AR_HEAT_INDEX_ALL_DATA+cmcId,JSON.toJSONString(popularityIndicatorListMap));
                        }else{//第一次初始化
                            popularityIndicatorListMap = this.makePopularityARIndexDataOfHbase(cmcId);
                        }
                        if(null != popularityIndicatorListMap && popularityIndicatorListMap.size() > 0){
                            rediscConfig.set(RedisKeysUtils.AR_HEAT_INDEX_ALL_DATA+cmcId,JSON.toJSONString(popularityIndicatorListMap));
                        }
                    }
                }
            }
            resultVo.setCode(ApiResultCodeUtils.BASE_SUCCESS.getCode());
            resultVo.setMessage(ApiResultCodeUtils.BASE_SUCCESS.getMsg());
        }catch (Exception e){
            e.printStackTrace();
            LogTrace.error("ar人气指标定数据组装到redis中",e);
            resultVo.setCode(ApiResultCodeUtils.SYSTEM_ERROR.getCode());
            resultVo.setMessage(ApiResultCodeUtils.SYSTEM_ERROR.getMsg());
        }
        return  resultVo;
    }

    /**
     * 第一次ar人气指标初始化redis数据
     * @param cmc_id
     * @return
     * @throws Exception
     */
    public Map<String,List<PopularityIndicator>> makePopularityARIndexDataOfHbase(String cmc_id) throws  Exception{
        int days = 0;
        Map<String,List<PopularityIndicator>> popularityIndicatorMap = new HashMap<>();
        for(int i=0;i<10;i++) {
            //获取十天内数据
            String rowKey = DateUtils.getNextDayDateYMD(days);
            days--;
            List<PopularityIndicator> popularityIndicatorList = getPopularityDayARIndexFromHbase(rowKey,cmc_id);
            if(popularityIndicatorList == null || popularityIndicatorList.size() == 0)continue;
            popularityIndicatorMap.put(rowKey, popularityIndicatorList);
        }
        return  popularityIndicatorMap;
    }
    /**
     * 组装ar人气医院指标从hbase获取近10天的数据
     * @param vo
     * @param cmc_id
     * @return
     * @throws Exception
     */
    public ApiPopularityARIndexVo makePopularityARIndexDataOfHbase(ApiPopularityARIndexVo vo,String cmc_id) throws  Exception{
        ChartVo chartVo = new ChartVo();
        vo.setChart(chartVo);
        List<String> x = new LinkedList<>();
        List<ApiChartYObject> y = new LinkedList<>();
        int days = 0;
        //数据放到缓存中
        //Map<String,PopularityIndicator> popularityIndicatorMap = new HashMap<>();
        Map<String,List<PopularityIndicator>> popularityIndicatorListMap = new HashMap<>();
        ApiChartYObject charY = null;
        PopularityIndicator pop = new PopularityIndicator();
        for(int i=0;i<10;i++){
            //获取十天内数据
            String rowKey = DateUtils.getNextDayDateYMD(days);
            days --;
            List<PopularityIndicator>  popList = getPopularityDayARIndexFromHbase(rowKey,cmc_id);//查询某个rowKey数据
            if(popList == null || popList.size() == 0) continue;
            popularityIndicatorListMap.put(rowKey,popList);
            for(int k=0;k<popList.size();k++){
                pop = popList.get(k);
                x.add(String.valueOf(pop.getCreateTime().getTime()));
                String ar =pop.getAr()!=null?pop.getAr().setScale(2,BigDecimal.ROUND_DOWN).toString():"";
                charY = new ApiChartYObject();
                charY.setValue(ar);
                charY.setComment(pop.getComment());
                charY.setScore(pop.getScore().toString());
                y.add(charY);
                //实体插入第一次的成交量和平均价格
                if(i == 0 && k == 0){
                    vo.setArScore(ar);
                    vo.setScore(pop.getScore()!=null?pop.getScore().toString():"");
                    vo.setResult(pop.getComment()!=null?pop.getComment():"");
                    vo.setTime(pop.getCreateTime()!=null?String.valueOf(pop.getCreateTime().getTime()):"");
                }
            }
        }
        chartVo.setX(x);
        chartVo.setY(y);
        //顺序反转
        Collections.reverse(x);
        Collections.reverse(y);
        //保存数据到redis中
        if(popularityIndicatorListMap != null && popularityIndicatorListMap.size() > 0){
            rediscConfig.set(RedisKeysUtils.AR_HEAT_INDEX_ALL_DATA+cmc_id,JSON.toJSONString(popularityIndicatorListMap));
        }
        return  vo;
    }
    /**
     * 组装ar人气医院指标从hbase获取24小时内的数据
     * @param vo
     * @param cmc_id
     * @return
     * @throws Exception
     */
    public ApiPopularityARIndexVo makePopularityARIndexHoursDataOfHbase(ApiPopularityARIndexVo vo,String cmc_id) throws  Exception{
        ChartVo chartVo = new ChartVo();
        vo.setChart(chartVo);
        List<String> x = new LinkedList<>();
        List<ApiChartYObject> y = new LinkedList<>();
        //数据放到缓存中
        ApiChartYObject charY = null;
        PopularityIndicator pop = new PopularityIndicator();
        Map<String,Object> hbaseData = new HashMap<>();
        int hourStrInt = LocalDateTime.now().getHour();
        String grailStr = "";
        Boolean firstFlag = true;
        for(int i=0;i>-2;i--){
            String rowKey = DateUtils.getNextDayDateYMD(i);
            Long hstart = System.currentTimeMillis();
            grailStr = hbaseBaseQueryComponent.selectByQualifierData(HbaseTableUtils.POPULARITY_INDICATOR_INFO_TABLE_NAME
                    , HbaseTableUtils.POPULARITY_INDICATOR_INFO_TABLE_FAMILY
                    , HbaseTableUtils.POPULARITY_INDICATOR_INFO_QUALIFIER
                    , cmc_id+"@"+rowKey);
            hbaseData.put(rowKey,grailStr);
            LogTrace.info("量化评估-人气意愿指标hbase数据查询", rowKey + "是否有数据", StringUtils.isBlank(grailStr)?"无数据":"有数据");
            LogTrace.info("量化评估-人气意愿指标hbase数据查询", rowKey + "耗时", String.valueOf(System.currentTimeMillis() - hstart));
        }
        for(int h=0;h<24;h++){
            String nowRowKey = DateUtils.getLastHourDateStrOfDate(h);
            grailStr = (String) hbaseData.get(nowRowKey);
            int nowHour = hourStrInt;
            if(hourStrInt == 0){
                hourStrInt = 23;
            }else{
                hourStrInt--;
            }
            if(StringUtils.isBlank(grailStr)) continue;
            Map<String, PopularityIndicator> volumeMap = JSON.parseObject(grailStr,new TypeReference<Map<String,PopularityIndicator>>(){});
            pop = volumeMap.get(String.valueOf(nowHour));
            if(pop != null && pop.getAr() != null && pop.getCreateTime() !=null && pop.getScore() != null && pop.getComment() != null){
                x.add(String.valueOf(pop.getCreateTime().getTime()));
                String ar =pop.getAr()!=null?pop.getAr().setScale(2,BigDecimal.ROUND_DOWN).toString():"";
                charY = new ApiChartYObject();
                charY.setValue(ar);
                charY.setComment(pop.getComment());
                charY.setScore(pop.getScore().toString());
                y.add(charY);
                //实体插入第一次的成交量和平均价格
                if(firstFlag){
                    vo.setArScore(ar);
                    vo.setScore(pop.getScore()!=null?pop.getScore().toString():"");
                    vo.setResult(pop.getComment()!=null?pop.getComment():"");
                    vo.setTime(pop.getCreateTime()!=null?String.valueOf(pop.getCreateTime().getTime()):"");
                    firstFlag = false;
                }
            }
        }
        chartVo.setX(x);
        chartVo.setY(y);
        //顺序反转
        Collections.reverse(x);
        Collections.reverse(y);
        vo.setSortId(4);
        vo.setClassify("人气意愿指标");
        vo.setExplanation("人气指标（AR）是通过比较一段周期内的开盘价在该周期价格中的高低，从而反映市场买卖人气的技术指标。当AR大于120，表明买方意愿强。当AR小于60，表明卖方意愿强。");
        //保存数据到redis中
        if(vo != null && x != null && x.size() >0 && y != null && y.size() >0){
            rediscConfig.set(RedisKeysUtils.AR_HEAT_INDEX_ALL_DATA_HOURS+cmc_id,JSON.toJSONString(vo),3600L);
        }
        return  vo;
    }
    /**
     * 获取ar人气单独某一天的某个某个货币数据
     * @param rowKey
     * @param cmc_id
     * @return
     * @throws HbaseCloseExcetion
     * @throws IOException
     * @throws HbaseGetTableExcetion
     * @throws HbaseConnectionExcetion
     */
    private PopularityIndicator getPopularityARIndexFromHbase(String rowKey, String cmc_id) throws Exception {
        Map<String,PopularityIndicator> popularityIndicatorMap = new HashMap<>();
        Long hstart = System.currentTimeMillis();
        String grailStr = hbaseBaseQueryComponent.selectByQualifierData(HbaseTableUtils.POPULARITY_INDICATOR_INFO_TABLE_NAME
                , HbaseTableUtils.POPULARITY_INDICATOR_INFO_TABLE_FAMILY
                , HbaseTableUtils.POPULARITY_INDICATOR_INFO_QUALIFIER
                , rowKey);
        LogTrace.info("hbase数据查询","是否存在数据"+rowKey,StringUtils.isBlank(grailStr)?"无数据":"有数据");
        LogTrace.info("量化评估-人气意愿指标hbase数据查询", rowKey + "耗时", String.valueOf(System.currentTimeMillis() - hstart));
        if (StringUtils.isBlank(grailStr)) return null;
        //获取指定货币量能变化
        Map<String, Object> volumeMap = JSON.parseObject(grailStr);
        if (volumeMap == null) return null;
        PopularityIndicator pop = JSON.parseObject(JSON.toJSONString(volumeMap.get(cmc_id)), PopularityIndicator.class);
        if(pop != null && pop.getComment() != null && pop.getId() != null && pop.getAr() != null && pop.getCreateTime() != null && pop.getScore() != null){
            return pop;
        }else{
            return  null;
        }
    }

    /**
     * 后期修改返回list，hbase结构改变，加入每个小时的数据
     * @param rowKey
     * @param cmc_id
     * @return
     * @throws Exception
     */
    private List<PopularityIndicator> getPopularityDayARIndexFromHbase(String rowKey, String cmc_id) throws Exception {
        List<PopularityIndicator> popList = new ArrayList<>();
        Map<String,PopularityIndicator> popularityIndicatorMap = new HashMap<>();
        Long hstart = System.currentTimeMillis();
        String grailStr = hbaseBaseQueryComponent.selectByQualifierData(HbaseTableUtils.POPULARITY_INDICATOR_INFO_TABLE_NAME
                , HbaseTableUtils.POPULARITY_INDICATOR_INFO_TABLE_FAMILY
                , HbaseTableUtils.POPULARITY_INDICATOR_INFO_QUALIFIER
                , cmc_id+"@"+rowKey);
        LogTrace.info("量化评估-人气意愿指标hbase数据查询", rowKey + "耗时", String.valueOf(System.currentTimeMillis() - hstart));
        if (StringUtils.isBlank(grailStr)) return null;
        //获取指定货币量能变化
        Map<String, PopularityIndicator> volumeMap = JSON.parseObject(grailStr,new TypeReference<Map<String,PopularityIndicator>>(){});
        if (volumeMap == null) return null;
        //循环24小时
        PopularityIndicator  pop = null;
        for(int i=23;i>=0;i--){
            String hourStr = String.valueOf(i);
            pop = volumeMap.get(hourStr);
            if(pop != null && pop.getComment() != null && pop.getId() != null && pop.getAr() != null && pop.getCreateTime() != null && pop.getScore() != null){
                popList.add(pop);
            }
        }
        return popList;
    }
    /**
     * 市场热度5分钟刷新缓存
     * @return
     */
    public ApiResultVo MarketHeatListToCache() {
        ApiResultVo resultVo = new ApiResultVo();
        resultVo.setDataStamp(System.currentTimeMillis());
        resultVo.setTradeId(LogTrace.getTrace().getTraceId());
        try {
            ApiMarketHeatVo listVo = new ApiMarketHeatVo();
            ApiEnergyVolumeChangeVo currencyVo = new ApiEnergyVolumeChangeVo();
            ApiCurrencyExchangeRatetVo exchangeVo = new ApiCurrencyExchangeRatetVo();
            ApiCurrencyDiagnosisScoreVo scoreVo = new ApiCurrencyDiagnosisScoreVo();
            //获取所有货币,组装每个需要诊断数据放到redis中
            List<CurrencyInfo>  allCurrencyInfo = redisCacheComponent.getCurrencyList();
            if(allCurrencyInfo != null && allCurrencyInfo.size() > 0){
                for(CurrencyInfo currency : allCurrencyInfo){
                    if(currency.getCurrencyDiagnosisFlag()){
                        this.MarketHeatListToCacheCalculation(listVo,currency.getCmcId());
                        this.makeEnergyVolumeChangeToCacheCalculation(currencyVo,currency.getCmcId());
                        this.marketCurrencyExchangeRateToCacheCalculation(exchangeVo,currency.getCmcId());
                        this.MakeCurrencyDiagnosisScore(scoreVo,currency.getCmcId());
                    }
                }
            }
            resultVo.setCode(ApiResultCodeUtils.BASE_SUCCESS.getCode());
            resultVo.setMessage(ApiResultCodeUtils.BASE_SUCCESS.getMsg());
        } catch (Exception e) {
            e.printStackTrace();
            LogTrace.error("5分钟组装市场热度放入redis中，缓存5分钟，触发",e);
            e.printStackTrace();
            resultVo.setCode(ApiResultCodeUtils.SYSTEM_ERROR.getCode());
            resultVo.setMessage(ApiResultCodeUtils.SYSTEM_ERROR.getMsg());
        }
        return resultVo;
    }
    /**
     * 市场热度5分钟组装数据到redis中
     * @param vo
     * @throws Exception
     */
    public void MarketHeatListToCacheCalculation(ApiMarketHeatVo vo,String cmc_id) throws Exception{
        MoreChartVo chartVo = new MoreChartVo();
        List<String> x = new LinkedList<>();
        List<ApiChartYObject> y = new LinkedList<>();
        List<ApiChartYObject> y1 = new LinkedList<>();

        chartVo.setX(x);
        chartVo.setY(y);
        chartVo.setY2(y1);
        vo.setChart(chartVo);
        vo.setSortId(1);
        vo.setClassify("市场热度");
        vo.setExplanation("市场热度指标主要统计近期谷歌关于货币名称的搜索热度，反映市场对该币种的关注度。");
        //获取当前小时
        String nowDateHoursStr = DateUtils.dateFormatString(new Date(),DateUtils.format_ymdh_x);
        String hourStr = nowDateHoursStr.substring(nowDateHoursStr.length()-2,nowDateHoursStr.length());
        int hourStrInt = Integer.valueOf(hourStr);
        int lastData =0; //最后一条数据记录
        String grailStr = null;
        Map<String,Object> hbaseData = new HashMap<>();//记录数据
        //获取两天hbase数据
        for(int day =0;day < 2;day++){
            String rowkey = DateUtils.getNextDayDateYMD(-day);//取rowkey
            Long hstart = System.currentTimeMillis();
            grailStr = hbaseBaseQueryComponent.selectByQualifierData(HbaseTableUtils.DAILY_MARKET_HEAT_TABLE_NAME
                    , HbaseTableUtils.MARKET_HEAT_TABLE_NAME_FAMILY
                    , HbaseTableUtils.MARKET_HEAT_TABLE_NAME_QUALIFIER
                    , cmc_id+"@"+rowkey);
            hbaseData.put(rowkey,grailStr);
            LogTrace.info("量化评估-市场热度hbase数据查询","是否存在数据"+rowkey,StringUtils.isBlank(grailStr)?"无数据":"有数据");
            LogTrace.info("量化评估-市场热度hbase数据查询","耗时"+rowkey,String.valueOf(System.currentTimeMillis()-hstart));
        }
        Long jStart = System.currentTimeMillis();
        ApiChartYObject charY = null;
        if(null != hbaseData){
            for(int i=0;i<24;i++){//24小时内数据
                String nowRowKey = DateUtils.getLastHourDateStrOfDate(i);
                grailStr = (String) hbaseData.get(nowRowKey);
                if(StringUtils.isBlank(grailStr)){
                    continue;
                }
                int nowHour = hourStrInt;
                if(hourStrInt==0){
                    hourStrInt =23;
                }else{
                    hourStrInt--;
                }
                Map<String,Object> quantum = (Map<String, Object>) JSON.parse(grailStr);
                Object o = quantum.get(nowHour);//获取当前时间数据
                if(o != null){
                    List<TrendsInfo> qua = JSON.parseArray(JSON.toJSONString(o),TrendsInfo.class);
                    for(int k =qua.size()-1;k>=0;k--){
                        TrendsInfo entry = qua.get(k);
                        //如果有一个属性不完整直接过滤
                        if(entry.getMarketheat() == null || entry.getAverageHotSearchIndex()==null) continue;
                        x.add(String.valueOf(entry.getCreateTime().getTime()));
                        charY = new ApiChartYObject();
                        charY.setValue(entry.getHotSearchIndex()!=null?entry.getHotSearchIndex().setScale(2,BigDecimal.ROUND_CEILING).toString():"");
                        charY.setScore(entry.getScore().toString());
                        charY.setComment(StringUtils.isNotBlank(entry.getResult())?entry.getResult():"");
                        y.add(charY);
                        charY = new ApiChartYObject();
                        charY.setValue(entry.getAverageHotSearchIndex()!=null?entry.getAverageHotSearchIndex().setScale(2,BigDecimal.ROUND_CEILING).toString():"");
                        charY.setScore(entry.getScore().toString());
                        charY.setComment(StringUtils.isNotBlank(entry.getResult())?entry.getResult():"");
                        y1.add(charY);
                       // y1.add(entry.getAverageHotSearchIndex()!=null?entry.getAverageHotSearchIndex().setScale(2,BigDecimal.ROUND_CEILING).toString():"");
                        //最新数据评分放入到最外层
                        if(lastData == 0){
                            vo.setAverageHeat(entry.getAverageHotSearchIndex()!=null?entry.getAverageHotSearchIndex().setScale(2,BigDecimal.ROUND_CEILING).toString():"");
                            vo.setMarketHeatScore(entry.getHotSearchIndex()!=null?entry.getHotSearchIndex().setScale(2,BigDecimal.ROUND_CEILING).toString():"");
                            vo.setScore(entry.getScore()!=null?entry.getScore().toString():"");
                            vo.setResult(entry.getResult()!=null?entry.getResult():"");
                            vo.setTime(entry.getCreateTime()!=null?String.valueOf(entry.getCreateTime().getTime()):"");
                            lastData++;
                        }
                    }
                }
            }
            Collections.reverse(x);
            Collections.reverse(y);
            Collections.reverse(y1);
            if(x.size() == 0 || y.size() == 0 || y1.size() == 0){
                vo = null;
            }else{
                //数据插入到redis中
                rediscConfig.set(RedisKeysUtils.DIAGNOSIS_MARKET_HEATLIST+cmc_id,JSON.toJSONString(vo),300L);
            }
        }else{
            vo = null;
        }
    }
    /**
     * 量能变化5分钟组装数据到redis中
     * @param vo
     * @throws Exception
     */
    public void makeEnergyVolumeChangeToCacheCalculation(ApiEnergyVolumeChangeVo vo,String cmc_id) throws Exception{
        MoreChartVo chartVo = new MoreChartVo();
        List<String> x = new LinkedList<>();
        List<ApiChartYObject> y = new LinkedList<>();
        List<ApiChartYObject> y1 = new LinkedList<>();
        chartVo.setX(x);
        chartVo.setY(y);
        chartVo.setY2(y1);
        vo.setSortId(2);
        vo.setClassify("量能变化");
        vo.setExplanation("分析价格涨跌与成交额之间的关系，可以很好地判断出近期货币价格的走势。");
        //获取当前小时
        String nowDateHoursStr = DateUtils.dateFormatString(new Date(),DateUtils.format_ymdh_x);
        String hourStr = nowDateHoursStr.substring(nowDateHoursStr.length()-2,nowDateHoursStr.length());
        int hourStrInt = Integer.valueOf(hourStr);
        int lastData=0; //记录最后一次数据
        String grailStr = null;
        Map<String,Object> hbaseData = new HashMap<>();//记录数据
        //获取两天hbase数据
        for(int day =0;day < 2;day++){
            String rowkey = DateUtils.getNextDayDateYMD(-day);//取rowkey
            Long hstart = System.currentTimeMillis();
            grailStr = hbaseBaseQueryComponent.selectByQualifierData(HbaseTableUtils.CURRENCY_DIAGNOSIS_QUANTUM_ENERGY_INFO_TABLE_NAME
                    , HbaseTableUtils.CURRENCY_DIAGNOSIS_QUANTUM_ENERGY_INFO_TABLE_FAMILY
                    , HbaseTableUtils.CURRENCY_DIAGNOSIS_QUANTUM_ENERGY_INFO_QUALIFIE
                    , cmc_id+"@"+rowkey);
            hbaseData.put(rowkey,grailStr);
            LogTrace.info("量化评估-量能变化hbase数据查询","是否存在数据"+rowkey,StringUtils.isBlank(grailStr)?"无数据":"有数据");
            LogTrace.info("量化评估-量能变化hbase数据查询","耗时"+rowkey,String.valueOf(System.currentTimeMillis()-hstart));
        }
        ApiChartYObject charY = null;
        //获取24小时数据
        for(int i=0;i<24;i++){
            String nowRowKey = DateUtils.getLastHourDateStrOfDate(i);
            grailStr = (String) hbaseData.get(nowRowKey);
            if(StringUtils.isBlank(grailStr)){
                continue;
            }
            int nowHour = hourStrInt;
            if(hourStrInt==0){
                hourStrInt =23;
            }else{
                hourStrInt--;
            }
            if(StringUtils.isBlank(grailStr))  continue;
            Map<String,Object> quantum = (Map<String, Object>) JSON.parse(grailStr);
            Object o = quantum.get(nowHour);//获取当前时间数据
            if(o != null){
                List<DiagnosisQuantumEnergy> qua = JSON.parseArray(JSON.toJSONString(o),DiagnosisQuantumEnergy.class);
                for(int k =qua.size()-1;k>=0;k--){
                    DiagnosisQuantumEnergy entry = qua.get(k);
                    if(entry == null || entry.getVolume24h() == null || entry.getTurnoverChangeRate() == null){
                        continue; //判断内容不完整直接过滤
                    }
                    x.add(String.valueOf(entry.getCreateTime().getTime()));
                    charY = new ApiChartYObject();
                    charY.setValue(entry.getVolume24h()!=null?entry.getVolume24h().setScale(2,BigDecimal.ROUND_CEILING).toString():"");
                    charY.setScore(entry.getScore()!=null?entry.getScore().toString():"0");
                    charY.setComment(StringUtils.isNotBlank(entry.getComment())?entry.getComment():"");
                    y.add(charY);
                    charY = new ApiChartYObject();
                    charY.setValue(entry.getPriceChangeRate()!=null?entry.getPriceChangeRate().multiply(BigDecimal.valueOf(100)).setScale(2,BigDecimal.ROUND_DOWN).toString():"");
                    charY.setScore(entry.getScore()!=null?entry.getScore().toString():"0");
                    charY.setComment(StringUtils.isNotBlank(entry.getComment())?entry.getComment():"");
                    y1.add(charY);
                    //y1.add(entry.getTurnoverChangeRate()!=null?entry.getTurnoverChangeRate().setScale(2,BigDecimal.ROUND_CEILING).toString():"");
                    //最新数据评分放入到最外层
                    if(lastData == 0){
                        vo.setVolume(entry.getVolume24h()!=null?entry.getVolume24h().setScale(2,BigDecimal.ROUND_CEILING).toString():"");
                        vo.setAverageVolumePrice(entry.getPriceChangeRate()!=null?entry.getPriceChangeRate().multiply(BigDecimal.valueOf(100)).setScale(2,BigDecimal.ROUND_DOWN).toString():"");
                        vo.setScore(entry.getScore()!=null?entry.getScore().toString():"");
                        vo.setResult(entry.getComment()!=null?entry.getComment():"");
                        vo.setTime(entry.getCreateTime()!=null?String.valueOf(entry.getCreateTime().getTime()):"");
                        lastData++;
                    }
                }
            }
        }
        //数据反转
        Collections.reverse(x);
        Collections.reverse(y);
        Collections.reverse(y1);
        vo.setChart(chartVo);
        if(x.size() == 0 || y.size() == 0 || y1.size() == 0){
            vo = null;
        }else{
            //数据插入到redis中
            rediscConfig.set(RedisKeysUtils.DIAGNOSIS_ENERGY_VOLUME_CHANGE+cmc_id,JSON.toJSONString(vo),300L);
        }
    }
    /**
     * 货币流动性5分钟组装数据到redis中
     * @param vo
     * @throws Exception
     */
    public void marketCurrencyExchangeRateToCacheCalculation(ApiCurrencyExchangeRatetVo vo,String cmc_id) throws  Exception{
        MoreChartVo chartVo = new MoreChartVo();
        vo.setChart(chartVo);
        List<String> x = new LinkedList<>();
        List<ApiChartYObject> y = new LinkedList<>();
        List<ApiChartYObject> y1 = new LinkedList<>();
        vo.setSortId(3);
        vo.setClassify("货币流动性");
        vo.setExplanation("换手率越高说明该币种交易频率越高，货币的流动性越好。");
        //获取当前小时
        String nowDateHoursStr = DateUtils.dateFormatString(new Date(),DateUtils.format_ymdh_x);
        String hourStr = nowDateHoursStr.substring(nowDateHoursStr.length()-2,nowDateHoursStr.length());
        int hourStrInt = Integer.valueOf(hourStr);
        int lastData =0;
        Map<String,Object> hbaseData = new HashMap();
        String grailStr = null;
        //获取两天hbase数据
        for(int day =0;day < 2;day++){
            String rowkey = DateUtils.getNextDayDateYMD(-day);//取rowkey
            Long hstart = System.currentTimeMillis();
            grailStr = hbaseBaseQueryComponent.selectByQualifierData(HbaseTableUtils.CURRENCY_LIQUIDITY_INFO_TABLE_NAME
                    , HbaseTableUtils.CURRENCY_LIQUIDITY_INFO_TABLE_FAMILY
                    , HbaseTableUtils.CURRENCY_LIQUIDITY_INFO_QUALIFIER
                    , cmc_id+"@"+rowkey);
            hbaseData.put(rowkey,grailStr);
            LogTrace.info("hbase数据查询","是否存在数据"+rowkey,StringUtils.isBlank(grailStr)?"无数据":"有数据");
            LogTrace.info("量化评估-货币流动性hbase数据查询","耗时"+rowkey,String.valueOf(System.currentTimeMillis()-hstart));
        }
        ApiChartYObject charY = null;
        for(int i=0;i<24;i++){
            String nowRowKey = DateUtils.getLastHourDateStrOfDate(i);
            grailStr = (String) hbaseData.get(nowRowKey);
            if(StringUtils.isBlank(grailStr)){
                continue;
            }
            int nowHour = hourStrInt;
            if(hourStrInt == 0){
                hourStrInt = 23;
            }else{
                hourStrInt--;
            }
            //if(StringUtils.isBlank(grailStr))continue;
            Map<String,Object> liquidity = (Map<String, Object>) JSON.parse(grailStr);
            Object o = liquidity.get(nowHour);//获取当前时间数据
            if(o != null){
                List<Liquidity> Liq = JSON.parseArray(JSON.toJSONString(o),Liquidity.class);
                for(int k =Liq.size()-1;k>=0;k--){
                    Liquidity entry = Liq.get(k);
                    if(entry == null || entry.getCoinExchangeRate() == null || entry.getTotalExchangeRate() == null){
                        continue; //判断内容不完整直接过滤
                    }
                    charY = new ApiChartYObject();
                    charY.setValue(entry.getCoinExchangeRate()!=null?entry.getCoinExchangeRate().multiply(BigDecimal.valueOf(100)).setScale(2,BigDecimal.ROUND_CEILING).toString():"");
                    charY.setScore(entry.getScore().toString());
                    charY.setComment(StringUtils.isNotBlank(entry.getComment())?entry.getComment():"");
                    y.add(charY);
                    charY = new ApiChartYObject();
                    charY.setValue(entry.getTotalExchangeRate().multiply(BigDecimal.valueOf(100)).setScale(2,BigDecimal.ROUND_DOWN).toString());
                    charY.setScore(entry.getScore().toString());
                    charY.setComment(StringUtils.isNotBlank(entry.getComment())?entry.getComment():"");
                    y1.add(charY);
                   // y1.add(entry.getTotalExchangeRate().multiply(BigDecimal.valueOf(100)).setScale(2,BigDecimal.ROUND_DOWN).toString());
                    x.add(String.valueOf(entry.getCreateTime().getTime()));
                    //最新数据评分放入到最外层
                    if(lastData==0){
                        vo.setMarketExchangeRate(entry.getTotalExchangeRate().multiply(BigDecimal.valueOf(100)).setScale(2,BigDecimal.ROUND_DOWN).toString());
                        vo.setCurrencyExchangeRate(entry.getCoinExchangeRate().multiply(BigDecimal.valueOf(100)).setScale(2,BigDecimal.ROUND_DOWN).toString());
                        vo.setScore(entry.getScore().toString());
                        vo.setResult(entry.getComment());
                        vo.setTime(entry.getCreateTime()!=null?String.valueOf(entry.getCreateTime().getTime()):"");
                        lastData++;
                    }
                }
            }
        }
        chartVo.setX(x);
        chartVo.setY(y);
        chartVo.setY2(y1);
        //顺序反转
        Collections.reverse(x);
        Collections.reverse(y);
        Collections.reverse(y1);
        if(x.size() == 0 || y.size() == 0 || y1.size() == 0){
            vo = null;
        }else{
            //数据插入到redis中
            rediscConfig.set(RedisKeysUtils.DIAGNOSIS_CURRENCY_EXCHANGE_RATE+cmc_id,JSON.toJSONString(vo),300L);
        }
    }

    /**
     * 获取Cmc的日K数据
     * @param cmcId
     * @param page
     * @return
     */
    public ApiResultVo getCmcKline(String cmcId , Integer page){
        ApiResultVo resultVo = new ApiResultVo();
        resultVo.setTradeId(LogTrace.getTrace().getTraceId());
        resultVo.setDataStamp(System.currentTimeMillis());

        try {

            String redisKey = "getCmcKline@"+cmcId+"@"+page;

            List<ApiKLineCmcData> kLineCmcDataList = null;

            if(!rediscConfig.exists(redisKey)) {
                LocalDateTime nowDate = LocalDateTime.now();

                LocalDateTime dateCalculate = nowDate.minusMonths(page);

                kLineCmcDataList = new ArrayList<>();

                while (nowDate.compareTo(dateCalculate)>0){
                    String rowKey = cmcId + DateUtils.localDateTimeFormatString( dateCalculate , DateUtils.format_ymds);

                    Map<String,Object> map = hbaseBaseQueryComponent.selectData(HbaseTableUtils.CURRENCY_INFO_K_LINE_TABLE_NAME ,rowKey);

                    if(map != null && map.size() > 0){
                        //某一天日K线
                        ApiKLineCmcData kLineCmcDay = JSON.parseObject(JSON.toJSONString(map), ApiKLineCmcData.class);

                        LogTrace.infoKvs("getCmcKline","rowKey",rowKey , "kLineCmcDay",kLineCmcDay!=null ? kLineCmcDay.toString():"NULL");
                        if(kLineCmcDay != null){
                            if(StringUtils.isBlank(kLineCmcDay.getDateTime())){
                                kLineCmcDay.setDateTime(DateUtils.localDateTimeToDate(dateCalculate).getTime()+"");
                            }
                            if(StringUtils.isBlank(kLineCmcDay.getVolume())){
                                kLineCmcDay.setVolume("0");
                            }
                            kLineCmcDataList.add(kLineCmcDay);
                        }
                    }

                    dateCalculate = dateCalculate.plusDays(1);
                }
                if(kLineCmcDataList.size() >0){
                    LogTrace.infoKvs("命中缓存","redisKey",redisKey);
                    //缓存12个小时
                    rediscConfig.set(redisKey , kLineCmcDataList , 60*60*1L);
                }
            }else{
                String dataStr = rediscConfig.get(redisKey);
                kLineCmcDataList = JSON.parseArray(dataStr , ApiKLineCmcData.class);
            }
            resultVo.setCode(ApiResultCodeUtils.BASE_SUCCESS.getCode());
            resultVo.setMessage(ApiResultCodeUtils.BASE_SUCCESS.getMsg());
            resultVo.setData(kLineCmcDataList);


        }catch (Exception e){
            LogTrace.error(e.getMessage() , e);
            resultVo.setCode(ApiResultCodeUtils.SYSTEM_ERROR.getCode());
            resultVo.setMessage(ApiResultCodeUtils.SYSTEM_ERROR.getMsg());
        }
        return resultVo;
    }

}
